• 데이터의 특성은 분포와 관계가 있다.
    • 모양에 해당하는 부분이 분포다.
    • 예를 들어, 원의 경우 반지름, 사각형의 경우 가로세로 길이가 모양에 해당한다.
  • 그림을 그려서 파악하는 이유는 봉우리가 몇 개인지를 파악하기 위해서
    • uni-modal(단봉)인지 multi-modal인지 파악하기 위해서
  • 관계의 경우에는 scatter plot이나 다른 모형들로 파악하게 된다.

Python으로 자료의 분포를 묘사하는 방법

복수개의 자료 즉, 자료 집합이 있을 때 자료 값의 분포 특성을 묘사하는 통계적인 방법을 기술 통계(descriptive statistics)라고 한다.

단일 자료 집합의 분포를 묘사하는 방법

자료 집합이 하나인 경우에는 보통 다음과 같은 방법으로 분포의 특성을 구하거나 전달할 수 있다.

  • 요약 통계
  • 히스토그램 (histogram)
  • 커널 밀도 (kernel density)

요약 통계

요약 통계는 자료 집합에 포함된 값의 최댓값, 최솟값, 평균값, 분산 등을 계산하는 방법을 말한다.

Python에서는 다음과 같은 방법을 사용한다.


In [1]:
np.random.seed(0)
x = np.random.normal(size=100)
x


Out[1]:
array([ 1.76405235,  0.40015721,  0.97873798,  2.2408932 ,  1.86755799,
       -0.97727788,  0.95008842, -0.15135721, -0.10321885,  0.4105985 ,
        0.14404357,  1.45427351,  0.76103773,  0.12167502,  0.44386323,
        0.33367433,  1.49407907, -0.20515826,  0.3130677 , -0.85409574,
       -2.55298982,  0.6536186 ,  0.8644362 , -0.74216502,  2.26975462,
       -1.45436567,  0.04575852, -0.18718385,  1.53277921,  1.46935877,
        0.15494743,  0.37816252, -0.88778575, -1.98079647, -0.34791215,
        0.15634897,  1.23029068,  1.20237985, -0.38732682, -0.30230275,
       -1.04855297, -1.42001794, -1.70627019,  1.9507754 , -0.50965218,
       -0.4380743 , -1.25279536,  0.77749036, -1.61389785, -0.21274028,
       -0.89546656,  0.3869025 , -0.51080514, -1.18063218, -0.02818223,
        0.42833187,  0.06651722,  0.3024719 , -0.63432209, -0.36274117,
       -0.67246045, -0.35955316, -0.81314628, -1.7262826 ,  0.17742614,
       -0.40178094, -1.63019835,  0.46278226, -0.90729836,  0.0519454 ,
        0.72909056,  0.12898291,  1.13940068, -1.23482582,  0.40234164,
       -0.68481009, -0.87079715, -0.57884966, -0.31155253,  0.05616534,
       -1.16514984,  0.90082649,  0.46566244, -1.53624369,  1.48825219,
        1.89588918,  1.17877957, -0.17992484, -1.07075262,  1.05445173,
       -0.40317695,  1.22244507,  0.20827498,  0.97663904,  0.3563664 ,
        0.70657317,  0.01050002,  1.78587049,  0.12691209,  0.40198936])

In [2]:
sp.stats.describe(x)


Out[2]:
DescribeResult(nobs=100L, minmax=(-2.5529898158340787, 2.2697546239876076), mean=0.059808015534484997, variance=1.0260874941564961, skewness=0.005171839713550013, kurtosis=-0.3783545566331328)

In [3]:
pd.Series(x).describe()


Out[3]:
count    100.000000
mean       0.059808
std        1.012960
min       -2.552990
25%       -0.643857
50%        0.094096
75%        0.737077
max        2.269755
dtype: float64

히스토그램

히스토그램은 자료 값이 가질 수 있는 범위를 몇 개의 구간으로 나누고 각 구간에 해당하는 값의 숫자 혹은 상대적 빈도를 계산하는 방법이다.

Python에서 히스토그램을 구하거나 그리기 위해 다음과 같은 방법을 사용한다.

matplotlib의 hist 함수는 다음과 같은 3개의 값을 반환한다.

  • n : 각 구간에 있는 값의 수 혹은 빈도 리스트
  • bins : 구간의 경계값 리스트
  • patches : 각 구간을 그리는 matplotlib patch 객체 리스트

In [4]:
n, bins, patches = plt.hist(x, bins=10)



In [5]:
n


Out[5]:
array([  1.,   5.,   7.,  13.,  17.,  18.,  16.,  11.,   7.,   5.])

In [6]:
bins


Out[6]:
array([-2.55298982, -2.07071537, -1.58844093, -1.10616648, -0.62389204,
       -0.1416176 ,  0.34065685,  0.82293129,  1.30520574,  1.78748018,
        2.26975462])

In [7]:
patches


Out[7]:
<a list of 10 Patch objects>

seaborn의 displot 함수 히스토그램에 대한 axis 객체만을 반환하는 대신 러그(rug), 커널 밀도(kernel density) 등을 표시하거나 특정한 확률 모형으로 fitting하는 추가 기능이 있다.


In [8]:
sns.distplot(x, rug=True);


커널 밀도

앞의 그림에서 곡선으로 나타난 것이 커널 밀도이다. 커널 밀도는 커널이라고 하는 특정 구간의 분포를 묘사하는 함수의 집합을 사용하여 전체 분포를 묘사하는 방법이다. 커널 밀도를 사용하면 분포의 전체 모양을 파악하기가 더 쉽다.

커널 밀도에 관한 자세한 내용은 scikit-learn 패키지의 사용자 가이드와 예제를 참조하면 된다.

복수개의 자료 집합의 분포를 묘사하는 경우

자료 집합이 하나가 아니라 두 개 이상이 있는 경우에는 두 자료 집합간의 관계를 알고 싶을 것이다.

만약 자료 집합의 수가 두 개이고 모두 연속적인 실수값이라면 스캐터 플롯(scatter plot)을 사용하면 된다. 스캐터 플롯을 그리기 위해서는 seaborn 패키지의 joinplot 함수를 사용한다. joinplot 함수는 스캐터 플롯뿐 아니라 각 변수의 히스토그램도 동시에 그린다.


In [10]:
np.random.seed(0)
tips = sns.load_dataset("tips")
sns.jointplot(x='total_bill', y='tip', data=tips)


Out[10]:
<seaborn.axisgrid.JointGrid at 0xbccdef0>

In [11]:
iris = sns.load_dataset('iris')
sns.jointplot("sepal_width", "petal_length", data=iris, kind='kde', space=0, zorder=0, n_levels=6)


Out[11]:
<seaborn.axisgrid.JointGrid at 0xc31d978>

만약 변수의 집합이 두 개 이상이라면 seaborn 패키지의 pairplot을 사용한다. pairplot은 grid 형태로 각 집합의 조합에 대해 히스토그램과 스캐터 플롯을 그린다.


In [12]:
sns.pairplot(iris, hue="species", markers=["o", "s", "D"], size=2)


Out[12]:
<seaborn.axisgrid.PairGrid at 0xbccdba8>

만약 두 자료 집합이 모두 이산적인 값 혹은 카테고리(category) 값을 가진다면 seaborn 패키지의 heatmap을 사용하면 된다.


In [13]:
flights = sns.load_dataset("flights")
flights = flights.pivot("month", "year", "passengers")
sns.heatmap(flights, annot=True, fmt="d", linewidths=1)


Out[13]:
<matplotlib.axes._subplots.AxesSubplot at 0xbccd710>

두 자료 집합 중 하나는 연속적인 값이고 다른 하나는 이산적인 혹은 카테고리 값인 경우에는 seaborn에서 제공하는 다음과 같은 플롯을 사용할 수 있다.


In [14]:
titanic = sns.load_dataset("titanic")
sns.factorplot(x="age", y="embark_town", hue="sex", row="class", data=titanic[titanic.embark_town.notnull()],
                orient="h", size=2, aspect=3.5, palette="Set3", kind="violin", split=True, cut=0, bw=.2)


Out[14]:
<seaborn.axisgrid.FacetGrid at 0x10c72a20>